#include "Vector.hh"

namespace snow
{

// 一系列辅助函数
template <class T, class Alloc>
typename Vector<T, Alloc>::iterator Vector<T, Alloc>::allocate_and_fill(size_type count, const value_type &value)
{
    iterator result = dataAllocator::allocate(count);
    // 全局函数，通过萃取技术决定使用fill_n或是反复调用construct
    uninitialized_fill_n(result, count, value);
    return result;
}

template <class T, class Alloc>
void Vector<T, Alloc>::fill_initialize(size_type count, const value_type &value)
{
    _start = allocate_and_fill(count, value);
    _finish = _start + count;
    _endOfStorage = _finish;
}

template <class T, class Alloc>
void Vector<T, Alloc>::destory_and_deallocate()
{
    if (capacity() != 0){
        dataAllocator::destory(_start, _finish);
        dataAllocator::deallocate(_start, capacity());
    }
}

template <class T, class Alloc>
void Vector<T, Alloc>::insert_aux(iterator position, const value_type &value)
{
    // 为什么这里又判断了一次finish和endofstorage
    // 因为这个函数不止给push_back一个调用
    if (_finish != _endOfStorage) { // 尚余空间

    } else { // 已无空间
        const size_type oldCap = capacity();
        const size_type newCap = oldCap == 0 ? 1 : 2 * oldCap;
        iterator newStart = dataAllocator::allocate(newCap);
        iterator newFinish = newStart;
        // 原vector中元素 copy 到newStart处
        newFinish = uninitialized_copy(_start, position, newStart);
        construct(newFinish, value); // 构造新元素value
        ++newFinish;
        // 将原vector中备用空间元素也copy到newFinish处
        // 侯捷疑惑？？？，这里完全是空的，snow疑惑？？？
        newFinish = uninitialized_copy(position, _finish, newFinish);
        // 析构并释放原vector元素
        destory_and_deallocate();
        _start = newStart;
        _finish = newFinish;
        _endOfStorage = newStart + newCap;
    }
}

template <class T, class Alloc>
template <class InputIterator>
void Vector<T, Alloc>::allocate_and_copy(InputIterator first, InputIterator last)
{
    _start = dataAllocator::allocate(last - first);
    _finish = uninitialized_copy(first, last, _start);
    _endOfStorage = _finish;
}

template <class T, class Alloc>
void Vector<T, Alloc>::push_back(const value_type &value)
{
    if (_finish != _endOfStorage) { // 尚有空间
        construct(_finish, value);
        ++_finish;
    } else { // 已无备用空间
        insert_aux(end(), value);
    }
}

} // namespace snow